import 'package:flutter/material.dart';

class PPButton extends StatefulWidget {
  /// 文本内容
  final String text;

  /// 字体大小
  final double? fontSize;

  /// 字体颜色
  final Color? textColor;

  /// 字体粗度
  final FontWeight fontWeight;

  /// 修剪字体
  final TextOverflow? overflow;

  /// 设置 ButtonStyle？ 对象
  final TextStyle? textStyle;

  /// 设置内间距。按级别从下往上生效覆盖 paddingLeft -> paddingHorizontal -> padding
  final double padding;
  final double? paddingHorizontal, paddingVertical;
  final double? paddingLeft, paddingTop, paddingRight, paddingBottom;

  /// 设置外边距
  final double margin;
  final double? marginHorizontal, marginVertical;
  final double? marginLeft, marginTop, marginRight, marginBottom;

  /// 背景色
  final Color? bgColor;

  /// 渐变背景色，如果同时设置了 bgColor 和 bgGradientColor， 则以渐变背景效果为主
  final List<Color>? bgGradientColor;

  /// 描边
  final Color? borderColor;
  final double borderWidth;

  /// 圆角值，
  /// 如果同时设置了[radius] 和单独圆角，则会覆盖掉对应位置的radius值
  final double radius;
  final double topLeftRadius;
  final double topRightRadius;
  final double btmLeftRadius;
  final double btmRightRadius;

  /// 最小、最大控件宽高
  final double minWidth, maxWidth, minHeight, maxHeight;

  /// 点击回调
  final VoidCallback? onPressed;

  /// 长按回调
  final VoidCallback? onLongPress;

  final double? width;
  final double? height;

  const PPButton(
    this.text, {
    Key? key,
    this.fontSize,
    this.textColor,
    this.fontWeight = FontWeight.normal,
    this.onPressed,
    this.onLongPress,
    this.textStyle,
    this.bgColor,
    this.bgGradientColor,
    this.radius = 0,
    this.borderColor,
    this.borderWidth = 0.0,
    this.topLeftRadius = 0,
    this.topRightRadius = 0,
    this.btmLeftRadius = 0,
    this.btmRightRadius = 0,
    this.padding = 0,
    this.paddingVertical,
    this.paddingHorizontal,
    this.paddingLeft,
    this.paddingTop,
    this.paddingRight,
    this.paddingBottom,
    this.margin = 0,
    this.marginVertical,
    this.marginHorizontal,
    this.marginLeft,
    this.marginTop,
    this.marginRight,
    this.marginBottom,
    this.minWidth = 0,
    this.minHeight = 0,
    this.maxWidth = double.infinity,
    this.maxHeight = double.infinity,
    this.overflow,
    this.width,
    this.height,
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() => _PPButtonState();
}

class _PPButtonState extends State<PPButton> {
  @override
  Widget build(BuildContext context) {
    return Container(
      constraints: _getBoxConstraints(),
      margin: _getEdgeInsets(false),
      padding: EdgeInsets.zero,
      width: widget.width,
      height: widget.height,
      decoration: _getBoxDecoration(),
      child: TextButton(
        style: ButtonStyle(
          tapTargetSize: MaterialTapTargetSize.shrinkWrap,
          padding: MaterialStateProperty.all(_getEdgeInsets(true)),
          elevation: MaterialStateProperty.all(0),
          overlayColor:
              MaterialStateProperty.resolveWith((states) => Colors.transparent),
        ),
        onPressed: widget.onPressed,
        onLongPress: widget.onLongPress,
        child: Text(
          widget.text,
          overflow: widget.overflow,
          style: TextStyle(
            fontSize: widget.fontSize,
            color: widget.textColor,
            fontWeight: widget.fontWeight,
            height: 1.1,
          ),
        ),
      ),
    );
  }

  /// 生成按钮内/外间距
  /// @Param innerInset  true ： 获取内间距，  false: 获取外边距
  EdgeInsetsGeometry _getEdgeInsets(bool innerInset) {
    // 默认内间距
    double edgeInsets = innerInset ? widget.padding : widget.margin;
    double left = edgeInsets;
    double top = edgeInsets;
    double right = edgeInsets;
    double bottom = edgeInsets;
    // 如果paddingHorizontal、 paddingVertical存在值，则覆盖默认内间距
    double? tempHhorizontal =
        innerInset ? widget.paddingHorizontal : widget.marginHorizontal;
    double? tempVertical =
        innerInset ? widget.paddingVertical : widget.marginVertical;
    if (tempHhorizontal != null && tempHhorizontal > 0) {
      left = tempHhorizontal;
      right = tempHhorizontal;
    }
    if (tempVertical != null && tempVertical > 0) {
      top = tempVertical;
      bottom = tempVertical;
    }
    // 如果paddingLeft等具体方向内间距存在值，则覆盖具体内间距
    double? tempLeft = innerInset ? widget.paddingLeft : widget.marginLeft;
    if (tempLeft != null && tempLeft > 0) {
      left = tempLeft;
    }
    double? tempTop = innerInset ? widget.paddingTop : widget.marginTop;
    if (tempTop != null && tempTop > 0) {
      top = tempTop;
    }
    double? tempRight = innerInset ? widget.paddingRight : widget.marginRight;
    if (tempRight != null && tempRight > 0) {
      right = tempRight;
    }
    double? tempBottom =
        innerInset ? widget.paddingBottom : widget.marginBottom;
    if (tempBottom != null && tempBottom > 0) {
      bottom = tempBottom;
    }
    return EdgeInsets.only(
      left: left,
      top: top,
      right: right,
      bottom: bottom,
    );
  }

  /// 最小、最大宽高限制
  BoxConstraints _getBoxConstraints() {
    return BoxConstraints(
        minWidth: widget.minWidth,
        maxWidth: widget.maxWidth,
        minHeight: widget.minHeight,
        maxHeight: widget.maxHeight);
  }

// 生成圆角、渐变背景
  BoxDecoration? _getBoxDecoration() {
    // 背景色，优先显示渐变色属性，否则显示存背景色
    List<Color>? bgGradientColor = widget.bgGradientColor;
    if (bgGradientColor != null && bgGradientColor.isNotEmpty) {
      // 如果颜色数组只有一个
      if (bgGradientColor.length == 1) {
        Color bgColor = bgGradientColor[0];
        bgGradientColor = [bgColor, bgColor];
      }
    } else if (widget.bgColor != null) {
      Color bgColor = widget.bgColor!;
      bgGradientColor = [bgColor, bgColor];
    }
    // 四圆角半径
    final double defaultRadius = widget.radius;
    double topLeftRadius = defaultRadius > 0 ? defaultRadius : 0;
    double topRightRadius = defaultRadius > 0 ? defaultRadius : 0;
    double bottomLeftRadius = defaultRadius > 0 ? defaultRadius : 0;
    double bottomRightRadius = defaultRadius > 0 ? defaultRadius : 0;
    // 分别设置四圆角半径
    if (widget.topLeftRadius > 0) {
      topLeftRadius = widget.topLeftRadius;
    }
    if (widget.topRightRadius > 0) {
      topRightRadius = widget.topRightRadius;
    }
    if (widget.btmLeftRadius > 0) {
      bottomLeftRadius = widget.btmLeftRadius;
    }
    if (widget.btmRightRadius > 0) {
      bottomRightRadius = widget.btmRightRadius;
    }

    BorderDirectional? border;
    if (widget.borderColor != null) {
      border = BorderDirectional(
        top: BorderSide(
            color: widget.borderColor!,
            width: widget.borderWidth,
            style: BorderStyle.solid),
        start: BorderSide(
            color: widget.borderColor!,
            width: widget.borderWidth,
            style: BorderStyle.solid),
        end: BorderSide(
            color: widget.borderColor!,
            width: widget.borderWidth,
            style: BorderStyle.solid),
        bottom: BorderSide(
            color: widget.borderColor!,
            width: widget.borderWidth,
            style: BorderStyle.solid),
      );
    }

    return BoxDecoration(
      shape: BoxShape.rectangle,
      border: border,
      borderRadius: BorderRadius.only(
          topLeft: Radius.circular(topLeftRadius),
          topRight: Radius.circular(topRightRadius),
          bottomLeft: Radius.circular(bottomLeftRadius),
          bottomRight: Radius.circular(bottomRightRadius)),
      gradient: bgGradientColor == null
          ? null
          : LinearGradient(colors: bgGradientColor),
    );
  }
}
